/*
 * @Author: Zeng Hugh
 * @Date: 2020-12-29 23:32:50
 * @Last Modified by: Zeng Hugh
 * @Last Modified time: 2020-12-29 23:32:57
 */

using RuleJudge.RuleData;
using SLANCommon.Enum;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace RuleJudge.Judge
{
    public class IP10 : BaseJudge
    {
        /// <summary>
        /// 构造函数，需要定义项目类型，管，通道信息
        /// </summary>

        // 定义全局常量：阳性判断参考值
        public const double T_Value_Cutoff = -1.04;
        public const double P_Value_Cutoff = -1.2;
        public const double IC_Ct_Cutoff = 35;

        public IP10()
        {
            Type = EProjectType.AQ;
            TubesNo = new List<int>() { 1, 1, 2, 2, 3, 3 }; // N,T,P管横向排列,否则会报错！！！
            ChannelsNo = new List<int>() { 1, 2, 1, 2, 1, 2 };
        }
        /// <summary>
        /// 判断逻辑
        /// 规则中只有结论（Conclusion）和自定义结果（CustomResults）可以回传到SLAN软件，其他数据都是为了编辑规则得出结论用的，不能回传。
        /// </summary>
        /// <param name="samples">样本列表</param>
        /// <returns>非空：SLAN会弹出内容信息框，进行提示</returns>
        public override string Judge(List<Sample> samples)
        {
            //在结果判断之前，先检查是否有需要判断的样本
            if (samples.Count == 0) return "无判断样本！";

            int FAM = 0;
            int VIC = 1;
            int HEX = 1;
            bool Negative_Control_Pass = false;
            bool Positive_Control_Pass = false;
            bool Leak_Negative_Control = false;
            bool Leak_Positive_Control = false;

            /*
            * ****************************************************************************************************************
            * 阴性质控判读标准：FAM通道和VIC/HEX通道均无扩增曲线。
            * ****************************************************************************************************************
            */
            #region 阴性质控(对照)的判读
            List<Sample> NegativeList = samples.Where(s => s.Type == SampleType.Negative).ToList();
            if(NegativeList.Count != 0)  //判断是否存在阴性质控
            {
                foreach (Sample sample in NegativeList)
                {
                    if (sample.Tubes[0].Targets[FAM].Result.Ct > 40 &&
                        sample.Tubes[0].Targets[VIC].Result.Ct > 40 &&
                        sample.Tubes[1].Targets[FAM].Result.Ct > 40 &&
                        sample.Tubes[1].Targets[VIC].Result.Ct > 40 &&
                        sample.Tubes[2].Targets[FAM].Result.Ct > 40 &&
                        sample.Tubes[2].Targets[VIC].Result.Ct > 40 )
                    {
                        sample.CustomResults.Add(new CustomResult() { Name = "结核感染特异性效应T细胞", Content = "阴性质控:符合要求" });
                        Negative_Control_Pass = true;
                    }
                    else
                    {
                        sample.CustomResults.Add(new CustomResult() { Name = "结核感染特异性效应T细胞", Content = "阴性质控:不符合要求" });
                        Negative_Control_Pass = false;
                    }
                }
                Leak_Negative_Control = false;

            }
            else
            {
                Leak_Negative_Control = true;
            }
            #endregion
            /*
            * ****************************************************************************************************************
            * 阳性质控判读标准：
            * ****************************************************************************************************************
            */
            #region 阳性质控(对照)的判读
            List<Sample> PositiveList = samples.Where(s => s.Type == SampleType.HighPositive).ToList();
            if (PositiveList.Count != 0)  //判断是否存在阳性质控
            {
                foreach (Sample sample in PositiveList)
                {
                    if (sample.Tubes[0].Targets[FAM].Result.Ct <= 40 &&
                        sample.Tubes[0].Targets[VIC].Result.Ct <= 40 &&
                        sample.Tubes[1].Targets[FAM].Result.Ct <= 40 &&
                        sample.Tubes[1].Targets[VIC].Result.Ct <= 40 &&
                        sample.Tubes[2].Targets[FAM].Result.Ct <= 40 &&
                        sample.Tubes[2].Targets[VIC].Result.Ct <= 40 )
                    {
                        sample.CustomResults.Add(new CustomResult() { Name = "结核感染特异性效应T细胞", Content = "阳性质控:符合要求" });
                        Positive_Control_Pass = true;
                    }
                    else
                    {
                        sample.CustomResults.Add(new CustomResult() { Name = "结核感染特异性效应T细胞", Content = "阳性质控:不符合要求" });
                        Positive_Control_Pass = false;
                    }
                }
                Leak_Positive_Control = false;

            }
            else
            {
                Leak_Positive_Control = true;
            }
            #endregion
            /*
            * ****************************************************************************************************************
            * 1. 待测(未知)样本数据分析计算：
            * (1) N管： ΔCt N = Ct值（FAM通道）- Ct值（VIC/HEX通道）；
            * (2) T管： ΔCt T = Ct值（FAM通道）- Ct值（VIC/HEX通道）；
            * (3) P管： ΔCt P = Ct值（FAM通道）- Ct值（VIC/HEX通道）；
            * (4) T值 = ΔCt T - ΔCt N;
            * (5) P值 = ΔCt P - ΔCt N;
            * 2. 阴阳性判断值：
            *       T值          P值          结果判定
            *   -----------------------------------------
            *     <= -1.04     任何情况         阳性
            *     > -1.04      <= -1.2          阴性
            *   -----------------------------------------
            * ****************************************************************************************************************
            */
            #region 待测（未知）样本结果判读
            List<Sample> UnknownList = samples.Where(s => s.Type == SampleType.Unknown).ToList();   //取出所有“待测样本”
            if (UnknownList.Count != 0)
            {
                foreach (Sample sample in UnknownList)
                {
                    #region 首先判断样本各反应管（孔）内参是否符合要求
                    bool IPC_Positive = false;
                    if (sample.Tubes[0].Targets[VIC].Result.Ct <= IC_Ct_Cutoff &&
                        sample.Tubes[1].Targets[VIC].Result.Ct <= IC_Ct_Cutoff &&
                        sample.Tubes[2].Targets[VIC].Result.Ct <= IC_Ct_Cutoff)
                    {
                        IPC_Positive = true;
                    }
                    else
                    {
                        IPC_Positive = false;
                        sample.CustomResults.Add(new CustomResult() { Name = "结核感染特异性效应T细胞", Content = "内参不合格，检测结果不可靠！" });
                    }
                    #endregion

                    #region 在内参符合要求情况下进行Ct值计算和结果判读
                    if (IPC_Positive)
                    {
                        // 1. 查看，当FAM通道Ct值是否为“Undetermined”或“No Ct”时，将Ct值替换成40进行计算
                        double Ct_N = double.IsPositiveInfinity(sample.Tubes[0].Targets[FAM].Result.Ct) == true ? 40 : sample.Tubes[0].Targets[FAM].Result.Ct;
                        double Ct_T = double.IsPositiveInfinity(sample.Tubes[1].Targets[FAM].Result.Ct) == true ? 40 : sample.Tubes[1].Targets[FAM].Result.Ct;
                        double Ct_P = double.IsPositiveInfinity(sample.Tubes[2].Targets[FAM].Result.Ct) == true ? 40 : sample.Tubes[2].Targets[FAM].Result.Ct;

                        // 2. ΔCt_N值，ΔCt_T值，ΔCt_P值，T值，P值计算
                        double Delta_Ct_N = Ct_N - sample.Tubes[0].Targets[VIC].Result.Ct;
                        double Delta_Ct_T = Ct_T - sample.Tubes[1].Targets[VIC].Result.Ct;
                        double Delta_Ct_P = Ct_P - sample.Tubes[2].Targets[VIC].Result.Ct;
                        double T_Value = Delta_Ct_T - Delta_Ct_N;
                        double P_Value = Delta_Ct_P - Delta_Ct_N;

                        // 3. 根据T值，P值进行结果判读，给出最终检测结论

                        if (T_Value <= T_Value_Cutoff && sample.Tubes[1].Targets[FAM].Result.Ct <= 38.5) // T值 <= -1.04s时，T管Ct值（FAM通道）<= 38.5，结果为“阳性”。
                        {
                            sample.CustomResults.Add(new CustomResult() { Name = "结核感染特异性效应T细胞", Content = "阳性" });
                        }

                        else if (T_Value <= T_Value_Cutoff && sample.Tubes[1].Targets[FAM].Result.Ct > 38.5) // T值 <= -1.04s时，T管Ct值（FAM通道）> 38.5，建议重新采集样本检测。
                        {
                            sample.CustomResults.Add(new CustomResult() { Name = "结核感染特异性效应T细胞", Content = "建议重新采集样本检测！" });
                        }

                        else if (T_Value > T_Value_Cutoff && P_Value <= P_Value_Cutoff) // T值 > -1.04s时，且P值 <= -1.2时，结果为“阴性”。
                        {
                            sample.CustomResults.Add(new CustomResult() { Name = "结核感染特异性效应T细胞", Content = "阴性" });
                        }

                        else if (T_Value > T_Value_Cutoff && P_Value > P_Value_Cutoff) // T值 > -1.04时，且P值 > -1.2时，则本次实验结果为“不确定”。
                        {
                            sample.CustomResults.Add(new CustomResult() { Name = "结核感染特异性效应T细胞", Content = "不确定！" });
                        }
                    }
                    #endregion
                }
            }
                #endregion

           /* ****************************************************************************************************************
            * (1) 实验中未设置阴阳性质控不影响判读，仅给出弹窗提醒缺少质控；
            * (2) 阴阳性质控不合格的，则给出提醒，但仍然进行判读。
            * ****************************************************************************************************************
            */
            #region 质控异常(质控不合格或缺失)弹窗警示
            if (!Negative_Control_Pass || !Positive_Control_Pass)
            {
                MessageBox.Show("阴阳性质控或阳性质控不符合要求！是否忽略？", "质控提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            if (Leak_Negative_Control || Leak_Positive_Control)
            {
                MessageBox.Show("本次实验缺少阴性质控或阳性质控！是否忽略？", "质控提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            #endregion

            return string.Empty;
        }
    }
}
